#include "ImgProc.h"

void erodeImage(IplImage* image) {
  int x, y;
  //IlpImage* erodedImage;
  for (y = 0; y < IMG_HEIGHT; y++) {
    for (x = 0; x < IMG_WIDTH; x++) {
      int temp = (y * IMG_WIDTH + x) * 3;

      if (y != 0 && y != IMG_HEIGHT && x != 0 && x != IMG_WIDTH) {
      } else {
        image->imageData[temp + 2] = 0;
        image->imageData[temp + 1] = 0;
        image->imageData[temp] = 0;
        continue;
      }

      if (image->imageData[temp] == 255) {
        int count = 0;

        count += image->imageData[((y - 1) * IMG_WIDTH + (x - 1)) * 3];
        count += image->imageData[((y - 1) * IMG_WIDTH + (x)) * 3];
        count += image->imageData[((y) * IMG_WIDTH + (x - 1)) * 3];
        count += image->imageData[((y + 1) * IMG_WIDTH + (x + 1)) * 3];
        count += image->imageData[((y + 1) * IMG_WIDTH + (x)) * 3];
        count += image->imageData[((y) * IMG_WIDTH + (x + 1)) * 3];
        count += image->imageData[((y - 1) * IMG_WIDTH + (x + 1)) * 3];
        count += image->imageData[((y + 1) * IMG_WIDTH + (x - 1)) * 3];

        if (count > 255 * 2) {
          image->imageData[temp + 2] = 255;
          image->imageData[temp + 1] = 255;
          image->imageData[temp] = 255;
        } else {
          image->imageData[temp + 2] = 0;
          image->imageData[temp + 1] = 0;
          image->imageData[temp] = 0;
        }
      }
    }
  }
  //erodedImage = image;
}

void findCentre(IplImage* image, coordinate_t &point, areaCoordinate_t &interestedArea) {
  int y, x;
  int avg = 0;
  int sum = 0;
  int x1, x2, y1, y2;

  x1 = interestedArea.point1.x;
  y1 = interestedArea.point1.y;
  x2 = interestedArea.point2.x;
  y2 = interestedArea.point2.y;

  for (y = y1; y < y2; y++) {
    for (x = x1; x < x2; x++) {
      int temp = (y * IMG_WIDTH + x) * 3;
      if (image->imageData[temp] == 255) {
        avg++;
      }
    }
  }
  avg /= 2;

  for (y = y1; y < y2; y++) {
    for (x = x1; x < x2; x++) {
      int temp = (y * IMG_WIDTH + x) * 3;
      if (image->imageData[temp] == 255) {
        sum++;
      }
    }

    if (sum >= avg) {
      point.y = y;
      break;
    }
  }

  //printf("cccccc  %d\n", (x2-x1)*(y2-y1));
  //printf("avg sum %d %d\n", avg, sum);
  sum = 0;

  for (x = x1; x < x2; x++) {
    for (y = y1; y < y2; y++) {
      int temp = (y * IMG_WIDTH + x) * 3;
      if (image->imageData[temp] == 255) {
        sum++;
      }
    }

    if (sum >= avg) {
      point.x = x;
      break;
    }
  }
}

void input(unsigned char *input, unsigned char *output, int channel, int height, int width) {
  int valueR, valueG, valueB, i, j;
  //printf("%d %d %d %d\n", input, channel,  height, width);
  for (i = 0; i < IMG_HEIGHT; i++) {
    for (j = 0; j < IMG_WIDTH; j++) {
      int temp = (i * IMG_WIDTH + j) * 3;
      valueR = input[temp + 2];
      valueG = input[temp + 1];
      valueB = input[temp + 0];

      if (valueR > 95 && valueG > 40 && valueB > 20 &&
      MAX(valueR, MAX(valueG,valueB)) - MIN(valueR, MIN(valueG, valueB)) > 15 &&
      ABS(valueR, valueG) > 15 && valueR > valueG && valueR > valueB) {
        output[temp + 2] = 255;
        output[temp + 1] = 255;
        output[temp] = 255;
      } else {
        output[temp + 2] = 0;
        output[temp + 1] = 0;
        output[temp] = 0;
      }
    }
  }

  //cvReleaseImage(&output);
  //cvReleaseImage(&input);
  return;
}

void crossline(BYTE* img, int x, int y, int thick) {
  int i, j;

  for (i = 0; i < IMG_HEIGHT; i++) {
    for (j = 0; j < IMG_WIDTH * 3; j++) {
      if ((j >= x - thick / 2 && j <= x + thick / 2) || (i > y - thick / 2 && i < y + thick / 2)) {  // X축에 등호를 사용하여 두께 보정
        img[i * IMG_WIDTH * 3 + j * 3 + 0] = 255;
        img[i * IMG_WIDTH * 3 + j * 3 + 1] = 0;
        img[i * IMG_WIDTH * 3 + j * 3 + 2] = 0;
      }
    }
  }
}

void circle(BYTE* img, int x, int y, int rad, int thick, int r, int g, int b) {
  int i, j;

  for (i = 0; i < IMG_HEIGHT; i++) {
    for (j = 0; j < IMG_WIDTH * 3; j++) {
      if ((i - y) * (i - y) + (j - x) * (j - x) >= (rad - thick) * (rad - thick)
          && (i - y) * (i - y) + (j - x) * (j - x) < (rad + thick) * (rad + thick)) {
        img[i * IMG_WIDTH * 3 + j * 3 + 0] = b;
        img[i * IMG_WIDTH * 3 + j * 3 + 1] = g;
        img[i * IMG_WIDTH * 3 + j * 3 + 2] = r;
      }
    }
  }
}

/*
 void square(BYTE* img, int x1, int x2, int y1, int y2, int thick) {
 int rwsize2 = WIDTHBYTES(24 * IMG_WIDTH);
 int i, j;

 for (i = 0; i < IMG_HEIGHT; i++) {
 for (j = 0; j < IMG_WIDTH * 3; j++) {
 if ((j >= x1 - thick / 2 && j <= x1 + thick / 2)
 && (i >= y1 && i <= y2)
 || (j >= x2 - thick / 2 && j <= x2 + thick / 2)
 && (i >= y1 && i <= y2)
 || (i >= y1 - thick / 2 && i <= y1 + thick / 2)
 && (j >= x1 - 1 && j <= x2 + 1)
 || (i >= y2 - thick / 2 && i <= y2 + thick / 2)
 && (j >= x1 - 1 && j <= x2 + 1)) { // x범위 +-1 >> 사각형 모서리 처리
 img[i * rwsize2 + j * 3 + 0] = 0;
 img[i * rwsize2 + j * 3 + 1] = 0;
 img[i * rwsize2 + j * 3 + 2] = 255;
 }
 }
 }
 }

 void cross(BYTE* img, int x, int y, int thick, int length, int r, int g,
 int b) {
 int rwsize2 = WIDTHBYTES(24 * IMG_WIDTH);
 int i, j;

 for (i = 0; i < IMG_HEIGHT; i++) {
 for (j = 0; j < IMG_WIDTH * 3; j++) {
 if (((j >= x - thick / 2 && j <= x + thick / 2)
 && (i >= y - length / 2 && i <= y + length / 2))
 || ((j >= x - length / 2 && j <= x + length / 2)
 && (i > y - thick / 2 && i < y + thick / 2))) { // X축에 등호를 사용하여 두께 보정
 img[i * rwsize2 + j * 3 + 0] = b;
 img[i * rwsize2 + j * 3 + 1] = g;
 img[i * rwsize2 + j * 3 + 2] = r;
 }
 }
 }
 }
 */
void findcircle(BYTE* img, BYTE* biimg, int x, int y, int rad, int thick, int r, int g, int b) {
  int flag = 0;
  int i, j;

  for (i = 0; i < IMG_HEIGHT; i++) {
    int temp = i * IMG_WIDTH;
    for (j = 0; j < IMG_WIDTH * 3; j++) {
      if ((i - y) * (i - y) + (j - x) * (j - x) >= (rad - thick) * (rad - thick)
          && (i - y) * (i - y) + (j - x) * (j - x) < (rad + thick) * (rad + thick)) {
        if (img[(temp + j) * 3] == 255) {
          img[(temp + j) * 3 + 0] = b;
          img[(temp + j) * 3 + 1] = g;
          img[(temp + j) * 3 + 2] = r;
        }
      }
    }
  }
}
/*
 void findmass(BYTE* img, BYTE*oriimg, int *radious){

 int SumX = 1, SumY = 1, count = 1;

 int initX = IMG_HEIGHT, initY = IMG_WIDTH;
 int lastX = 1, lastY = 1;
 int i, j, temp;

 //	printf("log:findmass\n");
 for (i = 5; i < IMG_HEIGHT-5; i++){			//가로 검색 및 무게중심
 for (j = 5; j < IMG_WIDTH-5; j++){
 temp =i*IMG_WIDTH;
 if (img[(temp+ j)*3] == 255){
 SumX += j;
 SumY += i;
 count++;
 if (i < initY)
 initY = i;
 lastY = i;	//y2(마지막 overwriten y value)
 }
 }
 }


 for (j = 5; j < IMG_WIDTH-5; j++){				//세로 검색
 for (i = 5; i < IMG_HEIGHT-5; i++){
 temp = i*IMG_WIDTH;
 if (img[(temp+ j)*3] == 255){
 if (j < initX)
 initX = j;
 lastX = j; //x2(마지막 overwriten x value)
 }
 }
 }
 if(SumX != 0 && SumY!= 0 && count != 0){
 //printf("%d, %d\n",SumX/count, SumY/count);
 //printf("%d, %d, %d, %d\n",initX, lastX, initY, lastY);
 if(((lastX -initX)/(lastY-initY)) < 3 && ((lastX -initX)/(lastY-initY)) > 1/3)
 {
 printf("maybe it's hand");
 // *radious = max((lastX - initX)/2, (lastY - initY)/2)*4/6;
 //printf("ra : %d\n", *radious);
 ///findcircle(oriimg, img, SumX / count, SumY / count, *radious, 4, 0, 0, 255);
 cross(oriimg, SumX / count, SumY / count, 2, 50, 0, 255, 0);
 square(oriimg, initX, lastX, initY, lastY, 2);
 printf("moving : %d\n",notMoving( SumX / count, SumY / count, countMovingX, countMovingY ));
 }
 }
 }
 */

/*
 void rgb2hsi(unsigned char *originalImg, unsigned short *hImg,
 unsigned char *sImg, unsigned char *iImg) {
 int i, j;
 double minc, angle;

 int red, green, blue;
 float fR, fG, fB;

 for (i = 0; i < IMG_HEIGHT; i++) {
 for (j = 0; j < IMG_WIDTH; j++) {
 red = originalImg[(i * IMG_WIDTH + j) * 3 + 2];
 green = originalImg[(i * IMG_WIDTH + j) * 3 + 1];
 blue = originalImg[(i * IMG_WIDTH + j) * 3 + 0];

 //정규화된 RGB로 변환
 if (red == 0 && green == 0 && blue == 0) {
 fR = 0.0f;
 fG = 0.0f;
 fB = 0.0f;
 } else {
 fR = (float) red / (red + green + blue);
 fG = (float) green / (red + green + blue);
 fB = (float) blue / (red + green + blue);
 }

 minc = MIN(fR, fG);
 minc = MIN(minc, fB);

 iImg[i * IMG_WIDTH + j] = (unsigned char) ((red + green + blue) / 3);

 if ((fR == fG) && (fG == fB)) {		// Gray Scale
 hImg[i * IMG_WIDTH + j] = 0;
 sImg[i * IMG_WIDTH + j] = 0;
 continue;
 } else {
 //sImg[i * width + j] = (BYTE)(255.0 - 3.0 * minc *255 / (red + green + blue));
 sImg[i * IMG_WIDTH + j] = (BYTE) (1.0f - 3.0f * minc * 255.0f);	//fR+fG+fB = 1.0이니까

 //angle = (((red - green) + (red - blue)) >> 1) / (double)(sqrt((double)((red - green) * (red - green) + (red - blue) * (green - blue))));
 angle = (fR - 0.5f * fG - 0.5f * fB)
 / (float) sqrt(
 (fR - fG) * (fR - fG) + (fR - fB) * (fG - fB));
 hImg[i * IMG_WIDTH + j] = (WORD) (acos(angle) * 57.29577951);
 }

 if (fB > fG)
 hImg[i * IMG_WIDTH + j] = (WORD) (360 - hImg[i * IMG_WIDTH + j]);

 //sImg[i * width + j] *= 255.0f;
 }
 }
 return;
 }
 */

/*
 void compareBGwithQ(queue_t* set, BYTE* input, BYTE* output) {
 int sum[IMG_WIDTH * IMG_HEIGHT];
 pthread_t tid[3];
 int length = (int) (set->front->data[0]);
 printf("compared BG start, length : %d\n", length);

 node_t* thisNode = set->front->next;

 for (int i = 0; i < length; i++) {
 for (int j = 0; j < IMG_WIDTH * IMG_HEIGHT; j++) { //현재큐의 데이터받아옴
 sum[j] += thisNode->data[j];
 }
 thisNode = thisNode->next; //큐 순번 옮김
 }
 if (length > 0) {
 for (int j = 0; j < IMG_WIDTH * IMG_HEIGHT; j++) {
 sum[j] = sum[j] / length; //평균 구함
 if ((input[j] - sum[j]) > 50 || (sum[j] - input[j]) > 50) {
 output[j] = 0; //차이값크면 0
 } else {
 output[j] = 255;
 }
 }
 }

 enqueue(set, input); // 새로들어온거 넣기
 if (length > 3) {
 dequeue(set);
 }

 }
 */
